package com.reservationserver.controller.user;

import com.alibaba.fastjson.JSONObject;
import com.reservationpojo.entity.Pingpong;
import com.reservationpojo.sendmessageevent.Sse;
import com.reservationpojo.utils.Result;
import com.reservationserver.mapper.user.UserPingpongMapper;
import com.reservationserver.service.user.UserPingpongservice;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;


@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/userpingpong")
@Tag(name = "用户乒乓球")
public class UserpingpongController {

    private final UserPingpongservice pingpongservice;

    private final UserPingpongMapper pingpongMapper;

    private final RedisTemplate redisTemplate;


    /**
     *预约位置，传递预约时间，位置，学号
     * @param pingpong 全不预约信息
     * @return 二维码
     * ce
     */
    @Operation(summary = "预约")
    @PostMapping("/reservation")
    public Result reservePosition(@RequestBody Pingpong pingpong)throws IOException{
        log.info("发送预约信息：{}",pingpong);
        if(!LocalDateTime.now().isBefore(pingpong.getReservationStartTime())){
            log.info("已不可预约当前时间段");
            return Result.error("已不可预约当前时间段");
        }
        List<LocalDateTime> timeList=pingpongMapper.reservationStartTimeList(pingpong.getReservedByid());
        int timelen=timeList.size();
        //不允许重复预约时
        if(!pingpongMapper.isrepeeate()){
            if(timelen>0&&timeList.get(timelen-1).toLocalDate().isEqual(pingpong.getReservationStartTime().toLocalDate())){
                log.info("禁止重复预约");
                return Result.error("禁止重复预约");
            }
        }
        if (pingpongMapper.isBlack(pingpong.getReservedByid())) {
            return Result.error("您已被拉黑，请联系管理员");
        }
        String pingpongCourt="pingpong"+pingpong.getPosition().charAt(0);
        //判断预约位置是否被关闭
        if(pingpongMapper.checkShutCourt(pingpongCourt)!=null){
            return Result.error("该位置已被关闭");
        }
        if(!Objects.equals(pingpongMapper.isFree(pingpong),null)){
            log.info("该位置已被预约");
            return Result.error("该位置已被预约");
        }
        String redisKey="pingpong"+pingpong.getPosition()+pingpong.getReservationStartTime().toString();
        redisTemplate.opsForValue().set(redisKey,pingpong.getReservedByid(),60, TimeUnit.SECONDS);
        Sse.saveEmitter("pingpong"+pingpong.getReservedByid());
        pingpongservice.reservePosition(pingpong);
        log.info("data:{}",pingpong);
        return Result.success("预约成功");
    }
    /**
     * 反序列化字节数组获取二维码
     * @param createTime 预约创建时间
     * @param uid 学号
     * @return 二维码
     * @throws IOException
     * ce
     */
    @Operation(summary = "获取二维码")
    @PostMapping("/selectQrcode")
    public Result selectQrcode( String createTime,String uid)throws IOException {
        log.info("获取指定预约的，创建时间：{}，学号:{}", createTime, uid);
        log.info("jian:{}","pingpong"+createTime + uid);
        String imageBase= (String) redisTemplate.opsForValue().get("pingpong"+createTime + uid);
        return Result.success(imageBase);
    }
    /**
     * 根据学号查询预约记录
     * 此方法在预约完成之后也调用
     * @param uid 学号
     * @return 全部预约记录
     * ce
     */
    @Operation(summary = "查询预约信息")
    @GetMapping("/checkReservation")
    public Result checkReservation(String uid,Integer page){
        log.info("查看预约信息");
        List<Pingpong> checkList=pingpongservice.checkReservation(uid,page);
        return Result.success(checkList);
    }
    /**
     * 删除预约
     * @param pingpong 预约时间 位置 id 创建时间
     * @return 无
     * ce
     */
    @Operation(summary = "删除预约")
    @PostMapping("/deleteReservation")
    public Result deletereservation(@RequestBody Pingpong pingpong){
        log.info("取消预约");
        Sse.removeEmitter("pingpong"+pingpong.getReservedByid());
        pingpongservice.deleteReservation(pingpong);
        return Result.success("已取消预约");
    }
    /**
     * 在时间按上显示剩余数量
     * @param starttimeList 开始时间
     * @return 对应时间段剩余数量
     * ce
     */
    @Operation(summary = "获取对应时段空闲位置数量")
    @PostMapping("/PingpongFreeNum")
    public Result pingpongFreeNum(@RequestParam("starttimeList") List<String> starttimeList){
        log.info("获取对应时间段空余位置数量start:{}",starttimeList);
        List<Integer> messageList = new ArrayList<>();
        List<String> courtShutDown= pingpongMapper.getCourt("pingpong");
        int len =courtShutDown.size();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
        for (int i = 0; i <starttimeList.size() ; i++) {
            LocalDateTime stime= LocalDateTime.parse(starttimeList.get(i),formatter);
            Integer num=48-pingpongMapper.freePositionNum(stime)-len*2;
            messageList.add(i,num);
        }
        return Result.success(JSONObject.toJSONString(messageList));
    }
    /**
     * 传递开始与结束时间
     * @param starttime 开始时间
     * @param endtime 结束时间
     * @return 已被占用的位置
     * ce
     */
    @Operation(summary = "空闲的位置")
    @PostMapping("/PingpongFreePosition")
    public Result pingpongFreePosition(
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime starttime,
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endtime){
        log.info("当前时间段空闲位置:{},{}",starttime,endtime);
        List<String> messageList=pingpongMapper.positionSelectByTime(starttime,endtime);
        List<String> stringList = Arrays.asList("1-A","1-B","2-A","2-B","3-A","3-B","4-A","4-B","5-A","5-B","6-A","6-B","7-A","7-B","8-A","8-B","9-A","9-B","10-A","10-B","11-A","11-B","12-A","12-B","13-A","13-B","14-A","14-B","15-A","15-B","16-A","16-B","17-A","17-B","18-A","18-B","19-A","19-B","20-A","20-B","21-A","21-B","22-A","22-B","23-A","23-B","24-A","24-B");
        List<Boolean> booleanList=Arrays.asList(false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false);
        for (String s : messageList) {
            for (int i = 0; i < stringList.size(); i++) {
                if (Objects.equals(s, stringList.get(i))) {
                    booleanList.set(i, true);
                }
            }
        }
        String message = JSONObject.toJSONString(booleanList);
        return Result.success(message);
    }
}
